﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Web.Mvc;
using Xenta.Attributes;
using Xenta.Utils;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Wizard.Controllers
{
    public sealed class PaymentController : ExtController
    {
        [Authenticate, HttpGet]
        public ActionResult Index(string flagMask)
        {
            var m = Svc.ProcessOperation("SearchPayments", new
            {
                CustomerID = JDM.Int32(Svc.Customer.EntityID),
                FlagMask = String.IsNullOrWhiteSpace(flagMask)
                    ? "Pending,Authorized,Captured"
                    : flagMask,
                SortBy = new[] 
                {
                    "CreatedOn"
                },
                SortDir = "Descending"
            }, new
            {
                DisclosureLevel = "Base"
            });
            return View(m);
        }

        [Authenticate, HttpGet, RestoreState]
        public ActionResult Show(int id)
        {
            var m = Svc.ProcessOperation("GetPayment", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            return View(m);
        }

        [Authenticate, HttpGet, RestoreState]
        public ActionResult Place(int invoiceID, string amount)
        {
            dynamic m = new ExpandoObject();

            m.InvoiceID = invoiceID;
            m.Amount = Svc.Price(amount);
            m.PaymentMethods = Svc.ProcessOperation("GetAvailablePaymentMethods", new
            {
                InvoiceID = invoiceID,
                PaymentAmount = m.Amount
            });

            return View(m);
        }

        [Authenticate, HttpPost, PersistState]
        public ActionResult Place(int invoiceID, Guid processorID, string amount)
        {
            try
            {
                var m = Svc.ProcessOperation("PlacePayment", new
                {
                    InvoiceID = invoiceID,
                    CustomerID = JDM.Int32(Svc.Customer.EntityID),
                    ProcessorID = processorID,
                    Amount = Svc.Price(amount)
                });
                return RedirectToAction(Loc.Act("Process").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }).Localized());
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Place").Set(new
            {
                invoiceID,
                amount
            }).Localized());
        }

        [Authenticate]
        public ActionResult Process(int id)
        {
            var m = Svc.ProcessOperation("GetPayment", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            return View(m);
        }

        [PersistState, ValidateInput(false)]
        public ActionResult IPN(Guid handlerID)
        {
            try
            {
                var attributes = new Dictionary<String, String>();
                foreach(var i in Request.Form.AllKeys)
                    attributes[i] = Request.Form[i];
                foreach(var i in Request.QueryString.AllKeys)
                    attributes[i] = Request.QueryString[i];
                var m = Svc.ProcessOperation("HandleInstantPaymentNotification", new
                {
                    HandlerID = handlerID,
                    Attributes = attributes
                });
                if(!Svc.IsAuthenticated)
                    return new EmptyResult();
                return RedirectToAction(Loc.Act("Show").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }).Localized());
            }
            catch(Exception ex)
            {
                return Content(ex.Message);
            }
        }

        [Authenticate, HttpGet, PersistState]
        public ActionResult PdfReport(int id)
        {
            var m = Svc.ProcessOperation("GetPayment", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(m == null)
                return HttpNotFound();
            if(JDM.Int32(m.Customer.EntityID) != JDM.Int32(Svc.Customer.EntityID))
                return new HttpUnauthorizedResult();
            try
            {
                long rptElapsedTime = 0;
                string rptMimeType = String.Empty;
                var rptData = Svc.BuildReport("PaymentPdfReport",
                    new Dictionary<String, String>
                    {
                        {"paymentID", JDM.String(m.EntityID)},
                        {"locale", JDM.String(Svc.Localization.Code)}
                    },
                    out rptMimeType,
                    out rptElapsedTime);
                string dwlExt = MimeTypeHelper.TypeToExt(rptMimeType);
                string dwlName = String.Format("payment_{0}_{1}.{2}", JDM.String(m.EntityID), JDM.String(m.Guid), dwlExt);
                return File(rptData, rptMimeType, dwlName);
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Show").Set(new
            {
                id = JDM.Int32(m.EntityID)
            }).Localized());
        }
    }
}
